﻿using AiQiuQuan.Sport.Model.Enums;
using Microsoft.EntityFrameworkCore;

namespace AiQiuQuan.Sport.WebApi.HangfireServices
{
    /// <summary>
    /// 活动订单自动取消
    /// </summary>
    public partial class AutoCancelOrderHangfireService
    {
        /// <summary>
        /// 活动订单自动取消
        /// </summary>
        public async Task ActivityExecuteAsync()
        {
            //更新活动状态为已结束
            await (await _activityRepository.UpdatePartialAsync())
                .Set(m => m.State, GameStateEnum.Finished)
                .Where(m => m.StartDate < DateTimeOffset.Now.Date)
                .ExecuteAsync();
            //取消未支付活动订单
            var orderList = await _gameOrderRepository.AsNoTracking()
                .Where(m => m.BusinessType == BusinessTypeEnum.Activity && m.State == GameOrderStateEnum.NotPay && m.CreateTime < DateTime.Now.AddMinutes(-5))
                .OrderBy(m => m.CreateTime).Take(100).ToListAsync();
            if (orderList.Any())
            {
                foreach (var order in orderList.GroupBy(m => m.BusinessId))
                {
                    await using (var redlock = await _distributedLockFactory.CreateLockAsync(order.Key.ToString("N"), TimeSpan.FromSeconds(20), TimeSpan.FromSeconds(8), TimeSpan.FromSeconds(1)))
                    {
                        if (redlock.IsAcquired)
                        {
                            var orderIdList = order.Select(m => m.ID).ToList();
                            var activity = await _activityRepository.FirstOrDefaultAsync(m => m.ID == order.Key);
                            var activityUserIdList = await _activityUserRepository.AsNoTracking().Where(m => orderIdList.Contains(m.GameOrderId)).Select(m => m.UserId).ToListAsync();
                            activity.TotalCount = activity.TotalCount - activityUserIdList.Count > 0 ? activity.TotalCount - activityUserIdList.Count : 0;

                            using (var uow = _unitOfWorkManager.Begin())
                            {
                                await _activityRepository.UpdateAsync(activity);
                                await (await _activityUserRepository.UpdatePartialAsync())
                                    .Set(m => m.PayState, PayOrderStateEnum.Canceled)
                                    .Set(m => m.JoinState, GameJoinStateEnum.AutoCancel)
                                    .Where(m => orderIdList.Contains(m.GameOrderId))
                                    .ExecuteAsync();
                                await (await _gameOrderRepository.UpdatePartialAsync())
                                    .Set(m => m.State, GameOrderStateEnum.Cancel)
                                    .Set(m => m.CancelTime, DateTimeOffset.Now)
                                    .Set(m => m.CancelCount, m => m.JoinCount)
                                    .Where(m => orderIdList.Contains(m.ID))
                                    .ExecuteAsync();

                                await uow.CompleteAsync();
                            }
                        }
                    }
                }
            }
        }
    }
}
